import { Repository } from 'typeorm';
import { AppDataSource } from '../config/database';
import { Design, RoomType, DesignStyle, DesignStatus } from '../entities/Design';
import { User } from '../entities/User';
import { AIProviderFactory, promptTemplates } from '../config/ai';
import { CreditService } from './CreditService';
import { OSSService } from './OSSService';
import { createError } from '../middleware/errorHandler';
import axios from 'axios';
import * as crypto from 'crypto';

export interface CreateDesignParams {
  userId: number;
  roomType: RoomType;
  designStyle: DesignStyle;
  originalImageFile: Express.Multer.File;
  customPrompt?: string;
}

export interface CreateTextToImageParams {
  userId: number;
  originalImageFile: Express.Multer.File;
  customPrompt: string;
}

export interface DesignResult {
  id: string;
  status: DesignStatus;
  generatedImageUrl?: string;
  creditsUsed: number;
  errorMessage?: string;
}

export interface DesignListParams {
  userId: number;
  page?: number;
  limit?: number;
  status?: DesignStatus;
  roomType?: RoomType;
  designStyle?: DesignStyle;
}

export interface PublicDesignListParams {
  page?: number;
  limit?: number;
  roomType?: RoomType;
  designStyle?: DesignStyle;
}

export interface DesignListResult {
  designs: Design[];
  total: number;
  page: number;
  limit: number;
  totalPages: number;
}

export class AIService {
  private creditService: CreditService;
  private ossService: OSSService;

  constructor() {
    this.creditService = new CreditService();
    this.ossService = new OSSService();
  }

  private getDesignRepository(): Repository<Design> {
    if (!AppDataSource.isInitialized) {
      throw new Error('数据库连接未初始化');
    }
    return AppDataSource.getRepository(Design);
  }

  private getUserRepository(): Repository<User> {
    if (!AppDataSource.isInitialized) {
      throw new Error('数据库连接未初始化');
    }
    return AppDataSource.getRepository(User);
  }

  /**
   * 检查AI服务是否可用
   */
  private checkAIAvailability(): void {
    if (!AIProviderFactory.hasAvailableProvider()) {
      throw createError('AI服务暂时不可用，请稍后重试', 503);
    }
  }

  /**
   * 生成设计提示词
   */
  private generatePrompt(roomType: RoomType, designStyle: DesignStyle, customPrompt?: string): string {
    if (customPrompt) {
      return customPrompt;
    }

    const roomTemplate = promptTemplates.roomDesign[roomType];
    const styleDescription = promptTemplates.styles[designStyle];
    
    return roomTemplate.replace('{style}', styleDescription);
  }

  /**
   * 优化文生图提示词
   */
  private optimizeTextToImagePrompt(userPrompt: string): string {
    // 为空房间装修设计优化提示词
    const basePrompt = "Interior design for an empty room, modern and stylish decoration, ";
    const qualityPrompt = ", high quality, professional interior design, realistic lighting, detailed textures, 4K resolution";
    
    return basePrompt + userPrompt + qualityPrompt;
  }

  /**
   * 下载图片并上传到OSS
   */
  private async downloadAndUploadImage(imageUrl: string, designId: string): Promise<string> {
    try {
      // 下载图片
      const response = await axios.get(imageUrl, {
        responseType: 'arraybuffer',
        timeout: 30000
      });

      const buffer = Buffer.from(response.data);
      const contentType = response.headers['content-type'] || 'image/png';
      const extension = contentType.includes('jpeg') ? 'jpg' : 'png';
      
      // 生成文件名
      const filename = `${designId}.${extension}`;
      
      // 创建符合Express.Multer.File接口的文件对象
      const fileObject: Express.Multer.File = {
        fieldname: 'image',
        originalname: filename,
        encoding: '7bit',
        mimetype: contentType,
        buffer: buffer,
        size: buffer.length,
        destination: '',
        filename: filename,
        path: '',
        stream: null as any
      };

      // 上传到OSS
      const uploadResult = await this.ossService.uploadFile(
        fileObject,
        {
          folder: 'ai-designs',
          filename,
          contentType,
          acl: 'public-read'
        }
      );

      return uploadResult.url;
    } catch (error) {
      console.error('下载并上传图片失败:', error);
      throw createError('图片处理失败', 500);
    }
  }

  /**
   * 创建AI设计任务
   */
  async createDesign(params: CreateDesignParams): Promise<DesignResult> {
    this.checkAIAvailability();

    const { userId, roomType, designStyle, originalImageFile, customPrompt } = params;

    // 检查用户是否存在
    const userRepository = this.getUserRepository();
    const user = await userRepository.findOne({ where: { id: userId } });
    if (!user) {
      throw createError('用户不存在', 404);
    }

    // 检查用户积分
    const creditInfo = await this.creditService.getUserCreditInfo(userId);
    if (creditInfo.creditBalance < 1) {
      throw createError('积分不足，请先购买积分', 400);
    }

    // 上传原始图片到OSS
    const filename = `${crypto.randomUUID()}-${originalImageFile.originalname}`;
    const uploadResult = await this.ossService.uploadFile(
      originalImageFile,
      {
        folder: 'room-images',
        filename,
        contentType: originalImageFile.mimetype,
        acl: 'public-read'
      }
    );

    // 生成提示词
    const prompt = this.generatePrompt(roomType, designStyle, customPrompt);

    // 创建设计记录
    const designRepository = this.getDesignRepository();
    const design = designRepository.create({
      userId,
      roomType,
      designStyle,
      originalImageUrl: uploadResult.url,
      prompt,
      status: 'pending',
      creditsUsed: 1
    });

    const savedDesign = await designRepository.save(design);

    // 异步处理图像生成
    this.processDesignGeneration(savedDesign.id).catch(error => {
      console.error(`设计生成失败 (ID: ${savedDesign.id}):`, error);
    });

    return {
      id: savedDesign.id,
      status: savedDesign.status,
      creditsUsed: savedDesign.creditsUsed
    };
  }

  /**
   * 创建文生图设计
   */
  async createTextToImageDesign(params: CreateTextToImageParams): Promise<DesignResult> {
    const { userId, originalImageFile, customPrompt } = params;

    // 检查用户是否存在
    const userRepository = this.getUserRepository();
    const user = await userRepository.findOne({ where: { id: userId } });
    if (!user) {
      throw createError('用户不存在', 404);
    }

    // 检查用户积分
    const creditInfo = await this.creditService.getUserCreditInfo(userId);
    if (creditInfo.creditBalance < 1) {
      throw createError('积分不足，请先购买积分', 400);
    }

    // 上传原始图片到OSS
    const filename = `${crypto.randomUUID()}-${originalImageFile.originalname}`;
    const uploadResult = await this.ossService.uploadFile(
      originalImageFile,
      {
        folder: 'room-images',
        filename,
        contentType: originalImageFile.mimetype,
        acl: 'public-read'
      }
    );

    // 优化提示词
    const optimizedPrompt = this.optimizeTextToImagePrompt(customPrompt);

    // 创建设计记录
    const designRepository = this.getDesignRepository();
    const design = designRepository.create({
      userId,
      originalImageUrl: uploadResult.url,
      prompt: optimizedPrompt,
      status: 'pending',
      creditsUsed: 1
    });

    const savedDesign = await designRepository.save(design);

    // 异步处理图像生成
    this.processDesignGeneration(savedDesign.id).catch(error => {
      console.error(`文生图设计生成失败 (ID: ${savedDesign.id}):`, error);
    });

    return {
      id: savedDesign.id,
      status: savedDesign.status,
      creditsUsed: savedDesign.creditsUsed
    };
  }

  /**
   * 处理设计生成（异步）
   */
  private async processDesignGeneration(designId: string): Promise<void> {
    const designRepository = this.getDesignRepository();
    const startTime = Date.now();

    try {
      // 更新状态为处理中
      await designRepository.update(designId, { status: 'processing' });

      const design = await designRepository.findOne({ where: { id: designId } });
      if (!design) {
        throw new Error('设计记录不存在');
      }

      // 扣除积分
      await this.creditService.useCredits({
        userId: design.userId,
        credits: design.creditsUsed,
        description: `AI室内设计生成 - ${design.roomType} (${design.designStyle})`,
        referenceId: designId,
        metadata: {
          roomType: design.roomType,
          designStyle: design.designStyle
        }
      });

      // 获取当前AI提供商并生成图像
      const aiProvider = AIProviderFactory.getCurrentProvider();
      if (!aiProvider) {
        throw new Error('没有可用的AI提供商');
      }

      console.log(`使用 ${aiProvider.getProviderName()} 提供商生成图像`);
      
      const response = await aiProvider.generateImage({
        prompt: design.prompt,
        originalImageUrl: design.originalImageUrl,
        size: '1024x1024',
        n: 1
      });

      const generatedImageUrl = response.imageUrl;
      if (!generatedImageUrl) {
        throw new Error('生成的图像URL为空');
      }

      // 下载并上传到OSS
      const ossImageUrl = await this.downloadAndUploadImage(generatedImageUrl, designId);

      // 更新设计记录
      const generationTime = Date.now() - startTime;
      await designRepository.update(designId, {
        status: 'completed',
        generatedImageUrl: ossImageUrl,
        generationTimeMs: generationTime,
        openaiRequestId: response.requestId || `${aiProvider.getProviderName()}-${Date.now()}`
      });

    } catch (error) {
      console.error(`设计生成失败 (ID: ${designId}):`, error);
      
      // 更新状态为失败
      await designRepository.update(designId, {
        status: 'failed',
        errorMessage: error instanceof Error ? error.message : '未知错误',
        generationTimeMs: Date.now() - startTime
      });

      // 如果已经扣除积分，需要退还
      try {
        const design = await designRepository.findOne({ where: { id: designId } });
        if (design) {
          await this.creditService.addCredits({
            userId: design.userId,
            credits: design.creditsUsed,
            validDays: 365,
            description: `AI设计生成失败退款 - ${designId}`,
            referenceId: designId
          });
        }
      } catch (refundError) {
        console.error(`积分退还失败 (ID: ${designId}):`, refundError);
      }
    }
  }

  /**
   * 获取设计详情
   */
  async getDesign(designId: string, userId?: number): Promise<Design> {
    const designRepository = this.getDesignRepository();
    const whereCondition: any = { id: designId };
    
    if (userId) {
      whereCondition.userId = userId;
    }

    const design = await designRepository.findOne({
      where: whereCondition,
      relations: ['user']
    });

    if (!design) {
      throw createError('设计记录不存在', 404);
    }

    return design;
  }

  /**
   * 获取用户设计列表
   */
  async getUserDesigns(params: DesignListParams): Promise<DesignListResult> {
    const { userId, page = 1, limit = 10, status, roomType, designStyle } = params;
    const designRepository = this.getDesignRepository();

    const whereCondition: any = { userId };
    if (status) whereCondition.status = status;
    if (roomType) whereCondition.roomType = roomType;
    if (designStyle) whereCondition.designStyle = designStyle;

    const [designs, total] = await designRepository.findAndCount({
      where: whereCondition,
      order: { createdAt: 'DESC' },
      skip: (page - 1) * limit,
      take: limit
    });

    return {
      designs,
      total,
      page,
      limit,
      totalPages: Math.ceil(total / limit)
    };
  }

  /**
   * 获取公开设计列表
   */
  async getPublicDesigns(params: PublicDesignListParams): Promise<DesignListResult> {
    const { page = 1, limit = 10, roomType, designStyle } = params;
    const designRepository = this.getDesignRepository();

    const whereCondition: any = { 
      isPublic: true,
      status: 'completed' // 强制只显示已完成的设计
    };
    if (roomType) whereCondition.roomType = roomType;
    if (designStyle) whereCondition.designStyle = designStyle;

    const [designs, total] = await designRepository.findAndCount({
      where: whereCondition,
      order: { createdAt: 'DESC' },
      skip: (page - 1) * limit,
      take: limit,
      relations: ['user'], // 包含用户信息用于展示
      select: {
        id: true,
        roomType: true,
        designStyle: true,
        originalImageUrl: true,
        generatedImageUrl: true,
        prompt: true,
        status: true,
        creditsUsed: true,
        generationTimeMs: true,
        isPublic: true,
        createdAt: true,
        updatedAt: true,
        user: {
          id: true,
          username: true,
          firstName: true,
          lastName: true
        }
      }
    });

    return {
      designs,
      total,
      page,
      limit,
      totalPages: Math.ceil(total / limit)
    };
  }

  /**
   * 更新设计公开状态
   */
  async updateDesignPublicStatus(designId: string, userId: number, isPublic: boolean): Promise<Design> {
    const designRepository = this.getDesignRepository();
    
    const design = await designRepository.findOne({
      where: { id: designId, userId }
    });

    if (!design) {
      throw createError('设计记录不存在', 404);
    }

    design.isPublic = isPublic;
    const updatedDesign = await designRepository.save(design);
    
    return updatedDesign;
  }

  /**
   * 删除设计记录
   */
  async deleteDesign(designId: string, userId: number): Promise<void> {
    const designRepository = this.getDesignRepository();
    
    const design = await designRepository.findOne({
      where: { id: designId, userId }
    });

    if (!design) {
      throw createError('设计记录不存在', 404);
    }

    // 删除OSS中的图片
    if (design.generatedImageUrl) {
      try {
        const urlParts = design.generatedImageUrl.split('/');
        const key = `ai-designs/${urlParts[urlParts.length - 1]}`;
        await this.ossService.deleteFile(key);
      } catch (error) {
        console.error('删除OSS文件失败:', error);
      }
    }

    await designRepository.remove(design);
  }

  /**
   * 获取设计统计信息
   */
  async getDesignStats(userId: number): Promise<any> {
    const designRepository = this.getDesignRepository();

    const [total, completed, processing, failed] = await Promise.all([
      designRepository.count({ where: { userId } }),
      designRepository.count({ where: { userId, status: 'completed' } }),
      designRepository.count({ where: { userId, status: 'processing' } }),
      designRepository.count({ where: { userId, status: 'failed' } })
    ]);

    return {
      total,
      completed,
      processing,
      failed,
      pending: total - completed - processing - failed
    };
  }
}